<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        function Person(name) {
            this.name = name
        }
        const person = new Person()
        console.log(person.__proto__)
        console.log(Person.prototype)

        // 原型链
        // ==> 规则2 所有的对象都有一个__proto__属性，属性值是一个对象

        // 1. Person.prototype也是一个对象，所以，它也有__proto__属性，属性值也是一个对象
        console.dir(Person)
        console.log(Person.prototype.__proto__) // __proto__访问到原型

        // ==> 原型上默认有一个constructor属性，指回构造函数

        // ==> 规则4 所有对象的隐式原型指向它的构造函数的显式原型
        Person.prototype.__proto__ === Object.prototype
        console.log(Person.prototype.__proto__ === Object.prototype)

        // Person.prototype 这个原型对象是 Object 这个构造函数创建的


        // 2. Object 它是一个构造函数
        // Object.prototype ===> 得到的也是一个原型
        // Object.prototype这个原型上默认有一个constructor属性，指向构造函数本身
        console.log(Object.prototype.constructor === Object)

        // Object.prototype            ===> 原型
        // Person.prototype.__proto__  ===> 原型
        console.log(Object.prototype)
        console.log(Person.prototype.__proto__)
        // 也就是，上面这两个指向的都是Object这个构造函数的原型
        // console.log(Object.prototype === Person.prototype.__proto__)

        // 我们说的原型，可以说是构造函数的原型，也可以说是实例的原型，指的都是同一个
        // 构造函数 通过prototype访问到它的原型
        // 实例     通过__proto__访问到它的原型

        // 3. Object.prototype
        // Object.prototype 它也是一个原型对象, 所以 它也有__proto__属性 
        console.log(Object.prototype)
        console.log(Object.prototype.__proto__ === null)

        // 正常的原型链终止到Object.prototype,  也就是Object.prototype.__proto__ === null
    </script>
</body>

</html>